﻿using Entity;
using IService;
using IRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Repository;

namespace Service
{
    public class InboundOrderService : IInboundOrderService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IPurchaseOrderRepository _purchaseRepo;
        private readonly IOrderDetailRepository _orderDetailRepo;
        private readonly IInventoryRepository _inventoryRepo;
        private readonly IInboundOrderRepository _inboundRepo;
        private readonly IProductInformationRepository _productRepo;
        private readonly IWarehouseRepository _warehouse;
        private readonly ILogger<InboundOrderService> _logger;


        // 注入仓储和事务接口    
        public InboundOrderService(IUnitOfWork unitOfWork,
                                   IInboundOrderRepository inboundRepo,
                                   IPurchaseOrderRepository purchaseRepo,
                                   IOrderDetailRepository orderDetailRepo,
                                   IInventoryRepository inventoryRepo,
                                   IProductInformationRepository productRepo,
                                   ILogger<InboundOrderService> logger,
                                   IWarehouseRepository warehouse)
        {
            _unitOfWork = unitOfWork;
            _purchaseRepo = purchaseRepo;
            _orderDetailRepo = orderDetailRepo;
            _inventoryRepo = inventoryRepo;
            _inboundRepo = inboundRepo;
            _productRepo = productRepo;
            _logger = logger;
            _warehouse = warehouse;

        }

        public async Task AddInboundOrderAsync(InboundOrderEntity order, List<InboundOrderDetailEntity2> details)
        {
            try
            {
                // 1. 业务校验（基于你的实体字段）
                ValidateOrderAndDetails(order, details);

                // 2. 填充默认值（关键：设置状态为2-待审核）
                var now = DateTime.Now;
                order.storage_status = "2"; // 强制待审核状态
                order.create_time = now;
                order.create_by = "当前登录用户ID"; // 从上下文获取
                order.is_delete = "0"; // 未删除

                // 3. 明细默认值
                foreach (var detail in details)
                {
                    detail.create_by = order.create_by;
                    detail.create_time = now;
                    detail.update_by = order.create_by;
                    detail.update_time = now;
                    detail.is_delete = "0";
                }

                // 4. 调用Repository保存
                await _inboundRepo.AddInboundOrderWithDetailsAsync(order, details);
                _logger.LogInformation($"入库单 {order.warehouse_receipt_no} 保存成功（待审核）");
            }
            catch (ArgumentException ex)
            {
                _logger.LogWarning(ex, "参数校验失败");
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "入库单保存失败");
                throw new Exception("系统异常，保存失败");
            }
        }

        public async Task AddInboundOrderAsync2(InboundOrderEntity order, List<InboundOrderDetailEntity2> details)
        {
            _logger.LogInformation("开始调用入库单服务，订单号：{No}", order.warehouse_receipt_no);
            try
            {
                if (string.IsNullOrEmpty(order.warehouse_receipt_no))
                    throw new ArgumentException("入库单号不能为空");
                if (details == null || details.Count == 0)
                    throw new ArgumentException("入库明细不能为空");
                if (details.Any(d => d.curr_stk_in_num <= 0))
                    throw new ArgumentException("入库数量必须大于0");

                await _inboundRepo.AddInboundOrderWithDetailsAsync2(order, details);
                _logger.LogInformation("入库单服务调用成功，订单号：{No}", order.warehouse_receipt_no);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "入库单服务调用失败，原因：{Message}", ex.Message);
                throw;
            }
        }

        public async Task AuditInboundOrderAsync(AuditRequest request)
        {
            await _unitOfWork.BeginTransactionAsync();
            try
            {
                // 1. 验证入库单状态
                var inboundOrder = await _inboundRepo.GetByIdAsync(
                    request.WarehouseReceiptId,
                    ((UnitOfWork)_unitOfWork).Transaction
                );
                if (inboundOrder == null || inboundOrder.is_delete == "1")
                    throw new ArgumentException("入库单不存在或已删除");
                if (inboundOrder.storage_status != "2")
                    throw new ArgumentException("入库单已审核，无法重复操作（当前状态：" + inboundOrder.storage_status + "）");

                // 2. 校验并补充仓库编码（核心修复：确保warehouse_code非空）
                if (!inboundOrder.warehouse_id.HasValue)
                    throw new ArgumentException("入库单未关联仓库，请检查数据");

                // 2.1 根据仓库ID查询仓库信息（获取warehouse_number作为仓库编码）
                var warehouse = await _warehouse.GetByIdAsync(
                    inboundOrder.warehouse_id.Value,
                    ((UnitOfWork)_unitOfWork).Transaction
                );
                if (warehouse == null || string.IsNullOrEmpty(warehouse.warehouse_number))
                    throw new ArgumentException($"仓库ID【{inboundOrder.warehouse_id.Value}】不存在或未配置编码");

                // 2.2 为入库单赋值仓库编码（确保后续库存插入时可用）
                inboundOrder.warehouse_code = warehouse.warehouse_number;

                // 3. 更新入库单审核状态
                inboundOrder.storage_status = request.IsApproved ? "4" : "3";
                inboundOrder.reviewer = request.Reviewer;
                inboundOrder.review_time = DateTime.Now;
                inboundOrder.note = request.Opinion;
                await _inboundRepo.UpdateAsync(
                    inboundOrder,
                    ((UnitOfWork)_unitOfWork).Transaction
                );

                if (request.IsApproved)
                {
                    // 4. 验证关联进货订单
                    var purchaseOrder = await _purchaseRepo.GetByOrderNoAsync(
                        inboundOrder.associated_order_no,
                        ((UnitOfWork)_unitOfWork).Transaction
                    );
                    if (purchaseOrder == null)
                        throw new ArgumentException($"关联进货订单【{inboundOrder.associated_order_no}】不存在");

                    // 5. 获取入库明细
                    var inboundDetails = await _inboundRepo.GetDetailsByReceiptIdAsync(
                        request.WarehouseReceiptId,
                        ((UnitOfWork)_unitOfWork).Transaction
                    );
                    if (inboundDetails == null || inboundDetails.Count == 0)
                        throw new ArgumentException("入库单无明细数据，无法审核通过");

                    // 6. 遍历明细处理库存
                    foreach (var inboundDetail in inboundDetails)
                    {
                        // 6.1 校验货品存在性
                        var productInfo = await _productRepo.GetByCodeAsync(
                            inboundDetail.product_code,
                            ((UnitOfWork)_unitOfWork).Transaction
                        );
                        if (productInfo == null)
                            throw new ArgumentException($"货品编码【{inboundDetail.product_code}】不存在");

                        // 6.2 校验进货明细存在性
                        var orderDetail = await _orderDetailRepo.GetByPurchaseIdAndProductIdAsync(
                            purchaseOrder.purchase_id,
                            productInfo.Product_ID,
                            ((UnitOfWork)_unitOfWork).Transaction
                        );
                        if (orderDetail == null)
                            throw new ArgumentException($"进货单【{purchaseOrder.purchase_order_no}】中无货品【{productInfo.product_name}】的明细");

                        // 6.3 更新进货明细已入库数量
                        orderDetail.stkIn_num += inboundDetail.curr_stk_in_num;
                        await _orderDetailRepo.UpdateStkInNumAsync(
                            orderDetail,
                            ((UnitOfWork)_unitOfWork).Transaction
                        );

                        // 6.4 处理库存（新增/更新）
                        var inventory = await _inventoryRepo.GetByProductCodeAndWarehouseIdAsync(
                            inboundDetail.product_code,
                            inboundOrder.warehouse_id.Value,
                            ((UnitOfWork)_unitOfWork).Transaction
                        );

                        if (inventory == null)
                        {
                            // 新增库存：查询有效库位
                            int currentWarehouseId = inboundOrder.warehouse_id.Value;
                            int? validLocationId = await _warehouse.GetValidLocationIdByWarehouseIdAsync(
                                currentWarehouseId,
                                ((UnitOfWork)_unitOfWork).Transaction
                            );
                            if (!validLocationId.HasValue)
                                throw new Exception($"仓库【{inboundOrder.warehouse_name}】未配置有效库位，请先添加库位");

                            // 查询库位名称
                            string locationName = await _warehouse.GetLocationNameByLocationIdAsync(
                                validLocationId.Value,
                                ((UnitOfWork)_unitOfWork).Transaction
                            );

                            // 创建新库存记录（使用已确认的warehouse_code）
                            await _inventoryRepo.AddInventoryAsync(
                                new InventoryEntity
                                {
                                    warehouse_id = currentWarehouseId,
                                    warehouse_code = inboundOrder.warehouse_code, // 此处已确保非空
                                    product_code = inboundDetail.product_code,
                                    current_inventory = inboundDetail.curr_stk_in_num,
                                    planned_outgoing_quantity = 0,
                                    location_id = validLocationId.Value,
                                    location = locationName,
                                    is_delete = 0
                                },
                                ((UnitOfWork)_unitOfWork).Transaction
                            );
                        }
                        else
                        {
                            // 更新现有库存
                            inventory.current_inventory += inboundDetail.curr_stk_in_num;
                            await _inventoryRepo.UpdateInventoryAsync(
                                inventory,
                                ((UnitOfWork)_unitOfWork).Transaction
                            );
                        }
                    }

                    // 7. 更新进货订单状态
                    var allOrderDetails = await _purchaseRepo.GetByPurchaseIdAsync(
                        purchaseOrder.purchase_id,
                        ((UnitOfWork)_unitOfWork).Transaction
                    );
                    bool isAllInbound = allOrderDetails.All(d => d.stkIn_num >= d.prod_num);
                    purchaseOrder.document_status = isAllInbound ? "4" : "8";
                    await _purchaseRepo.UpdateAsync(
                        purchaseOrder,
                        ((UnitOfWork)_unitOfWork).Transaction
                    );
                }

                // 8. 提交事务
                await _unitOfWork.CommitTransactionAsync();
                _logger.LogInformation($"入库单【{inboundOrder.warehouse_receipt_no}】审核成功，结果：{(request.IsApproved ? "通过" : "驳回")}");
            }
            catch (ArgumentException ex)
            {
                await _unitOfWork.RollbackTransactionAsync();
                _logger.LogWarning(ex, $"入库单审核业务异常：{ex.Message}");
                throw new Exception($"审核失败：{ex.Message}");
            }
            catch (Exception ex)
            {
                await _unitOfWork.RollbackTransactionAsync();
                _logger.LogError(ex, $"入库单审核系统异常");
                throw new Exception("审核失败：系统异常，请联系管理员", ex);
            }
        }

        public async Task<(List<InboundQueryResult> Data, int Total)> QueryInboundPagedAsync(InboundQueryParam param)
        {
            var total = await _inboundRepo.GetInboundTotalAsync(param);
            var allData = await _inboundRepo.GetInboundListAsync(param);

            // 内存分页（若数据量大，建议改为SQL分页）
            var pagedData = allData
                .Skip((param.PageIndex - 1) * param.PageSize)
                .Take(param.PageSize)
                .ToList();

            return (pagedData, total);
        }

        /// <summary>
        /// 校验主表和明细的必填参数（适配InboundOrderDetailEntity2）
        /// </summary>
        private void ValidateOrderAndDetails(InboundOrderEntity order, List<InboundOrderDetailEntity2> details)
        {
            // 主表校验（保持不变）
            if (string.IsNullOrWhiteSpace(order.warehouse_receipt_no))
                throw new ArgumentException("入库单号不能为空");
            if (!order.warehouse_id.HasValue || order.warehouse_id <= 0)
                throw new ArgumentException("请选择仓库");
            if (string.IsNullOrWhiteSpace(order.storage_type))
                throw new ArgumentException("请选择入库类型");
            if (order.date_of_storage == default)
                throw new ArgumentException("请选择入库日期");
            if (order.suppliers_id <= 0)
                throw new ArgumentException("请选择供应商");
            if (order.handler_id <= 0)
                throw new ArgumentException("请选择经办人");

            // 明细表校验（修正字段名）
            if (details == null || details.Count == 0)
                throw new ArgumentException("请至少添加一条入库明细");
            for (int i = 0; i < details.Count; i++)
            {
                var detail = details[i];
                if (string.IsNullOrWhiteSpace(detail.product_code))
                    throw new ArgumentException($"第{i + 1}条明细：货品编号不能为空");
                if (detail.curr_stk_in_num <= 0)
                    throw new ArgumentException($"第{i + 1}条明细：入库数量必须大于0");
            }
        }




    }
}
